package com.rongchuang.autoopendevice.service.impl;

import com.rongchuang.autoopendevice.service.EmailListenerService;
import com.sun.mail.imap.IMAPFolder;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.mail.*;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class QQEmailListenerServiceImpl {
    @Autowired
    QQMessageProcessing qqMessageProcessing;
    @Value("${email.host}")
    private String host;

    @Value("${email.user}")
    private String user;

    @Value("${email.password}")
    private String password;

    @Value("${email.mbox}")
    private String mbox;

    @Value("${email.freq}")
    private int freq;
    private static final Logger LOGGER = LoggerFactory.getLogger(QQEmailListenerServiceImpl.class);

    private Folder folder;
    private Store store;

    @PostConstruct
    public void init() {
        monitorMailbox();
    }

    public void monitorMailbox() {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        try {
            Properties props = System.getProperties();
            Session session = Session.getInstance(props, null);
            store = session.getStore("imap");
            store.connect(host, user, password);
            folder = store.getFolder(mbox);
            if (folder == null || !folder.exists()) {
                LOGGER.error("Invalid folder");
                return;
            }
            folder.open(Folder.READ_WRITE);
            folder.addMessageCountListener(qqMessageProcessing);
            idleOrPoll();
        } catch (Exception ex) {
            LOGGER.error("Error in monitoring mailbox", ex);
        } finally {
            executor.shutdown();
            closeFolderAndStore();
        }
    }

    private void idleOrPoll() throws Exception {
        boolean supportsIdle = folder instanceof IMAPFolder;
        while (true) {
            try {
                if (supportsIdle) {
                    ((IMAPFolder) folder).idle();
                } else {
                    Thread.sleep(freq);
                    folder.getMessageCount();
                }
            } catch (FolderClosedException ex) {
                LOGGER.error("-------意外关闭连接-------");
                reconnect();
            }
        }
    }

    private void reconnect() {
        LOGGER.error("-------重新连接-------");
        try {
            if (folder != null && folder.isOpen()) {
                folder.close(false);
            }
            if (store != null && store.isConnected()) {
                store.close();
            }
            // Reconnect
            store.connect(host, user, password);
            folder = store.getFolder(mbox);
            folder.open(Folder.READ_WRITE);
            folder.addMessageCountListener(qqMessageProcessing);
        } catch (MessagingException e) {
            LOGGER.error("Error reconnecting", e);
        }
    }

    private void closeFolderAndStore() {
        try {
            if (folder != null && folder.isOpen()) {
                folder.close(false);
            }
            if (store != null && store.isConnected()) {
                store.close();
            }
        } catch (MessagingException e) {
            LOGGER.error("Error closing folder or store", e);
        }
    }
}
